package cn.stylefeng.guns.sys.modular.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.base.auth.context.LoginContextHolder;
import cn.stylefeng.guns.base.consts.ConstantsContext;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.core.exception.BusException;
import cn.stylefeng.guns.sys.core.exception.enums.BusExceptionEnum;
import cn.stylefeng.guns.sys.core.util.DateUtil;
import cn.stylefeng.guns.sys.core.util.ExcelFormatUtil;
import cn.stylefeng.guns.sys.core.util.PinYinUtil;
import cn.stylefeng.guns.sys.modular.system.controller.BaseFrontController;
import cn.stylefeng.guns.sys.modular.system.entity.*;
import cn.stylefeng.guns.sys.modular.system.mapper.*;
import cn.stylefeng.guns.sys.modular.system.model.params.*;
import cn.stylefeng.guns.sys.modular.system.model.result.MdzxResult;
import cn.stylefeng.guns.sys.modular.system.model.result.ZxTzqkResult;
import cn.stylefeng.guns.sys.modular.system.model.result.ZxTzqkViewResult;
import cn.stylefeng.guns.sys.modular.system.model.result.ZxYusuanResult;
import cn.stylefeng.guns.sys.modular.system.service.BtyZxGhsLockService;
import cn.stylefeng.guns.sys.modular.system.service.MdzxService;
import cn.stylefeng.roses.core.reqres.response.ErrorResponseData;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * <p>
 * 门店装修表 服务实现类
 * </p>
 *
 * @author jiangge
 * @since 2020-11-02
 */
@Service
public class MdzxServiceImpl extends ServiceImpl<MdzxMapper, Mdzx> implements MdzxService {
    Logger logger = LoggerFactory.getLogger(MdzxServiceImpl.class);

    @Resource
    private ProjectMapper projectMapper;

    @Resource
    private ZxYusuanMapper zxYusuanMapper;

    @Resource
    private ZxChengbenMapper zxChengbenMapper;

    @Resource
    private ZxKemuMapper zxKemuMapper;

    @Resource
    private ZxHuopinMapper huopinMapper;

    @Resource
    private ZxTzqkMapper zxTzqkMapper;

    @Resource
    private BtyZxGhsLockService ghsLockService;
    @Resource
    private BtyZxGhsLockMapper ghsLockMapper;


    @Override
    public List<MdzxResult> customList(MdzxParam param) {
        return this.baseMapper.customList(param);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData add(MdzxParam param) {

        //选择了门店，门店名称以选择的门店为准
        if (param.getBtyBrandId() != 0) {
            //同一个店不能添加两次
            QueryWrapper<Mdzx> wrapper = new QueryWrapper<>();
            wrapper = wrapper.eq("bty_brand_id", param.getBtyBrandId());
            wrapper = wrapper.eq("del_flag", 0);
            List<Mdzx> data = this.baseMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(data)) {
                return new ErrorResponseData("添加失败，同一门店只能添加一次");
            }

            //选择了门店，门店名称以选择的门店为准
            Project project = projectMapper.selectById(param.getBtyBrandId());
            if (project != null) {
                param.setBtyBrandIdView(project.getName());
            }
        }

        //没有选择门店，以输入的门店名称为准
        if (param.getBtyBrandId() == 0 && !"".equals(param.getBtyBrandIdView())) {
            //没有选择门店，以输入的门店名为准
            QueryWrapper<Mdzx> wrapper = new QueryWrapper<>();
            wrapper = wrapper.eq("bty_brand_id_view", param.getBtyBrandIdView());
            wrapper = wrapper.eq("del_flag", 0);
            List<Mdzx> data = this.baseMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(data)) {
                return new ErrorResponseData("添加失败，同一门店只能添加一次");
            }
        }

        //门店助记码
        String pinInCode = PinYinUtil.getPinYinCode(param.getBtyBrandIdView());
        param.setMdZhujima(pinInCode);
        param.setCreateUser(LoginContextHolder.getContext().getUserId());
        param.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        param.setDelFlag(0);
        //负责人


        Mdzx entity = getEntity(param);

        //门店名同步到工程表
        if (entity.getMdBianma() != null && !entity.getMdBianma().equals("")) {
            QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("yaoma", entity.getMdBianma());
            Project project = projectMapper.selectOne(queryWrapper);
            if (project != null) {
                project.setName(entity.getBtyBrandIdView());
                projectMapper.updateById(project);
            }
        }


        this.save(entity);


        //复制预算模板
        List<ZxYusuanResult> paramlist = zxYusuanMapper.listYusuantemplateByPinpai(param.getPinpai());

        if (ToolUtil.isNotEmpty(paramlist)) {
            List<ZxYusuan> yusuanlist = new ArrayList<>();
            for (ZxYusuanResult param1 : paramlist) {
                ZxYusuan ys = new ZxYusuan();
                ys.setXuhao(param1.getXuhao());
                ys.setXiangmu(param1.getXiangmu());
                ys.setJine(param1.getJine());
                ys.setBtyZxMdzxId(entity.getBtyZxMdzxId());
                ys.setCreateUser(LoginContextHolder.getContext().getUserId());
                ys.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                ys.setCreateTime(new Date());
                yusuanlist.add(ys);
            }
            boolean b = zxYusuanMapper.batchAdd(yusuanlist);
            if (!b) {
                logger.error("复制预算数据失败!");
                throw new BusException(BusExceptionEnum.ERR_COPY_YUSUAN);
            }

        }
        return new SuccessResponseData();
    }

    @Override
    public ResponseData delete(MdzxParam param) {
        Mdzx mdzx = this.getById(getKey(param));
        //如果店名为空，可以删除
        if (mdzx.getBtyBrandIdView() != null && !"".equals(mdzx.getBtyBrandIdView()) && ToolUtil.isNotEmpty(mdzx.getChengbenHeji()) && mdzx.getChengbenHeji().compareTo(BigDecimal.ZERO) != 0) {
            //已经存在门店装修成本数据不可删除
            ZxChengbenParam zxChengbenParam = new ZxChengbenParam();
            zxChengbenParam.setBtyZxMdzxId(param.getBtyZxMdzxId());
            Integer count = zxChengbenMapper.selectCountByBtyZxMdzxId(zxChengbenParam);
            if (count != null && count > 0) {
                return new ErrorResponseData("删除失败，该门店已经在报销数据中使用");
            }
            //已经存在门店预算数据不可删除
            ZxYusuanParam zxYusuanParam = new ZxYusuanParam();
            zxYusuanParam.setBtyZxMdzxId(param.getBtyZxMdzxId());
            Integer countYusuan = zxYusuanMapper.selectCountByBtyZxMdzxId(zxYusuanParam);
            if (countYusuan != null && countYusuan > 0) {
                return new ErrorResponseData("删除失败，该门店已经在门店预算数据中使用");
            }
            //已经存在投资情况数据不可删除-tzqk表中有数据
            Integer countTzqk = zxTzqkMapper.selectCountByBtyZxMdzxId(zxChengbenParam);
            if (countTzqk != null && countTzqk > 0) {
                return new ErrorResponseData("删除失败，该门店已经存在投资情况数据");
            }
        }
        String dm = mdzx.getBtyBrandIdView() + "(删除)";
        //逻辑删除
        mdzx.setDelFlag(1);
        mdzx.setBtyBrandIdView(dm);
        mdzx.setUpdateUser(LoginContextHolder.getContext().getUserId());
        mdzx.setUpdateUserName(LoginContextHolder.getContext().getUser().getName());
        this.updateById(mdzx);
        return SuccessResponseData.success();
    }

    @Override
    public ResponseData update(MdzxParam param) {
        Mdzx oldEntity = getOldEntity(param);
        Mdzx newEntity = getEntity(param);
        //门店名称
//        Project project = projectMapper.selectById(param.getBtyBrandId());
//        if (project != null) {
//            newEntity.setBtyBrandIdView(project.getName());
//        }

        //修改之前的名称与修改之后的名称不一致，要保证修改之后的名称不能是已经存在的门店
//        if (!oldEntity.getBtyBrandIdView().equals(newEntity.getBtyBrandIdView())) {
//            QueryWrapper<Mdzx> wrapper = new QueryWrapper<>();
//            wrapper = wrapper.eq("bty_brand_id_view", newEntity.getBtyBrandIdView());
//            wrapper = wrapper.eq("del_flag", 0);
//            List<Mdzx> data = this.baseMapper.selectList(wrapper);
//            if (CollectionUtil.isNotEmpty(data)) {
//                return new ErrorResponseData("修改失败，门店名称不能修改为：" + newEntity.getBtyBrandIdView() + "，装修数据中已经有该门店。");
//            }
//
//        }

        //查询该店名是否存在
        int con = baseMapper.getName(param.getBtyBrandIdView());
        if (!oldEntity.getBtyBrandIdView().equals(newEntity.getBtyBrandIdView()) && con > 0){
            return ResponseData.error("该店名已存在，不可修改。");
        }

        //门店名同步到工程表
        if (param.getMdBianma() != null && !param.getMdBianma().equals("")) {
            QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("yaoma", param.getMdBianma());
            Project project = projectMapper.selectOne(queryWrapper);
            //未确认状态才可修改
            if (project != null && project.getDmSta().equals(0)) {
                project.setName(param.getBtyBrandIdView());
                projectMapper.updateById(project);
                newEntity.setBtyBrandId(project.getId());
            }
        }


        //门店助记码
        String pinInCode = PinYinUtil.getPinYinCode(newEntity.getBtyBrandIdView());
        newEntity.setMdZhujima(pinInCode);
        newEntity.setUpdateUser(LoginContextHolder.getContext().getUserId());
        newEntity.setUpdateUserName(LoginContextHolder.getContext().getUser().getName());
        ToolUtil.copyProperties(newEntity, oldEntity);
        BigDecimal yjtz = newEntity.getYujiTouzi() == null ? BigDecimal.ZERO : newEntity.getYujiTouzi();
        int num = yjtz.compareTo(new BigDecimal(0));
        //预计投资大于0,更新状态status为1
        if (num > 0) {
            newEntity.setStatus("1");
        }

        BigDecimal mianji;
        BigDecimal jine;
        if (ToolUtil.isNotEmpty(newEntity.getMianji())){
            mianji = new BigDecimal(newEntity.getMianji());
            if (mianji.compareTo(new BigDecimal(200)) == -1) {
                jine = new BigDecimal(80000);
            } else if (mianji.compareTo(new BigDecimal(200)) != -1 && mianji.compareTo(new BigDecimal(220)) == -1) {
                jine = new BigDecimal(100000);
            } else if (mianji.compareTo(new BigDecimal(220)) != -1 && mianji.compareTo(new BigDecimal(240)) == -1) {
                jine = new BigDecimal(120000);
            } else {
                jine = new BigDecimal(140000);
            }
            //根据面积更新桌椅金额
            ZxYusuan zxYusuan = new ZxYusuan();
            zxYusuan.setJine(jine);
            zxYusuanMapper.update(zxYusuan, new QueryWrapper<ZxYusuan>().eq("bty_zx_mdzx_id", newEntity.getBtyZxMdzxId())
                    .eq("xuhao", "31"));
        }

        this.updateById(newEntity);
        return ResponseData.success();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData updateByParam(MdzxParam param) {
        Mdzx oldEntity = getOldEntity(param);
        Mdzx newEntity = getEntity(param);
        newEntity.setUpdateUser(LoginContextHolder.getContext().getUserId());
        newEntity.setUpdateUserName(LoginContextHolder.getContext().getUser().getName());
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
        return ResponseData.success();
    }

    @Override
    public MdzxResult findBySpec(MdzxParam param) {
        return this.baseMapper.findBySpec(param);
    }

    @Override
    public List<MdzxResult> findListBySpec(MdzxParam param) {
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(MdzxParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo findPageBySpecDz(MdzxParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.dzList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    private Serializable getKey(MdzxParam param) {
        return param.getBtyZxMdzxId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private Mdzx getOldEntity(MdzxParam param) {
        return this.getById(getKey(param));
    }

    private Mdzx getEntity(MdzxParam param) {
        Mdzx entity = new Mdzx();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    @Override
    public void calculateChengbenAndYusuan(Long btyZxMdzxId, BigDecimal danjia) {
        Mdzx mdzx = this.baseMapper.selectById(btyZxMdzxId);

        BigDecimal mianji = new BigDecimal(0);
        BigDecimal price = new BigDecimal(0);
        BigDecimal jine = new BigDecimal(0);
        if (ToolUtil.isNotEmpty(mdzx) && ToolUtil.isNotEmpty(mdzx.getMianji())) {
            mianji = new BigDecimal(mdzx.getMianji());
            if (mianji.compareTo(new BigDecimal(200)) == -1) {
                jine = new BigDecimal(80000);
            } else if (mianji.compareTo(new BigDecimal(200)) != -1 && mianji.compareTo(new BigDecimal(220)) == -1) {
                jine = new BigDecimal(100000);
            } else if (mianji.compareTo(new BigDecimal(220)) != -1 && mianji.compareTo(new BigDecimal(240)) == -1) {
                jine = new BigDecimal(120000);
            } else {
                jine = new BigDecimal(140000);
            }
            price = mianji.multiply(danjia == null ? BigDecimal.ZERO : danjia);
            jine = jine.add(price);
        }
        //预算合计
        BigDecimal sumYuSuan = zxYusuanMapper.getSumOfYuSuan(btyZxMdzxId);

        mdzx.setYusuanHeji(sumYuSuan == null ? jine : sumYuSuan);
        //成本合计-20201125-feng-成本的改变有关：1.投资情况导入时，2.投资情况金额变化时，3.报销单改变时
        //BigDecimal sumOfChengBen = zxChengbenMapper.getSumOfChengBen(btyZxMdzxId);

        //预计投资
        BigDecimal yuJiTouzi = mdzx.getYujiTouzi() == null ? BigDecimal.ZERO : mdzx.getYujiTouzi();
        mdzx.setYujiTouzi(yuJiTouzi);
        //成本总计
        BigDecimal chengbenHeji = mdzx.getChengbenHeji() == null ? BigDecimal.ZERO : mdzx.getChengbenHeji();
        mdzx.setChengbenHeji(chengbenHeji);

        //投资剩余=预计投资-成本总计
        mdzx.setTouzishengyu(mdzx.getYujiTouzi().subtract(mdzx.getChengbenHeji()));
        this.baseMapper.updateById(mdzx);
    }

    /**
     * 更新成本合计，并重新计算投资剩余
     *
     * @param param
     * @return
     */
    @Override
    public ResponseData updateAndcalculateChengbenAndYusuan(MdzxParam param) {
        if (ToolUtil.isNotEmpty(param.getBtyZxMdzxId())){
            Mdzx mdzx = this.getById(param.getBtyZxMdzxId());
            mdzx.setChengbenHeji(param.getChengbenHeji());
            this.updateById(mdzx);
            //重新计算
            calculateChengbenAndYusuan(param.getBtyZxMdzxId(), BigDecimal.ZERO);
        }
        return SuccessResponseData.success();
    }


    @Override
    public ResponseEntity<byte[]> exportExcel(HttpServletRequest request, HttpServletResponse response, Long btyZxMdzxId) {
        try {
            logger.info(">>>>>>>>>>开始导出excel>>>>>>>>>>");
            //TODO-1 要导出的数据内容
            List<ZxTzqkViewResult> list = this.getTzqk(btyZxMdzxId);
            BaseFrontController baseFrontController = new BaseFrontController();
            //文件名称
            Mdzx mdzx = this.baseMapper.selectById(btyZxMdzxId);
            return baseFrontController.buildResponseEntity(export(list, mdzx), mdzx.getBtyBrandIdView() + ".xls");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(">>>>>>>>>>导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }


    private InputStream export(List<ZxTzqkViewResult> list, Mdzx mdzx) {
        logger.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        // 保留1000条数据在内存中
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet();
        // 设置报表头样式cell样式
        CellStyle header = ExcelFormatUtil.headSytle(wb);
        // 报表体样式
        CellStyle content = ExcelFormatUtil.contentStyle(wb);

        //TODO-2 每一列字段名
        String[] titles = new String[]{"一级科目", "二级科目", "金额", "备注"};

        // 字段名所在表格的宽度，数量应与列字段名数量一致
        int[] ints = new int[]{5000, 5000, 5000, 5000};


        //TODO-3 设置总标题内容，没有可略过
        //设置第一行标题：指定 4 个参数，起始行，结束行，起始列，结束列,
        int firstRow = 1;
        int lastRow = 1;
        int firstCol = 1;
        int lastCol = 4;
        SXSSFRow row1 = sheet.createRow(0);
        SXSSFCell cell0 = row1.createCell(0);
        CellRangeAddress regionFist = new CellRangeAddress(firstRow - 1, lastRow - 1, firstCol - 1, lastCol - 1);
        sheet.addMergedRegion(regionFist);
        //设置每一列的字段名
        cell0.setCellValue("投资情况表");
        cell0.setCellStyle(header);

        SXSSFRow row2 = sheet.createRow(1);
        SXSSFCell cell20 = row2.createCell(0);
        //设置每一列的字段名
        cell20.setCellValue("店名");
        cell20.setCellStyle(header);

        CellRangeAddress region21 = new CellRangeAddress(firstRow, firstRow, 1, 3);
        sheet.addMergedRegion(region21);

        SXSSFCell cell21 = row2.createCell(1);
        //设置每一列的字段名
        cell21.setCellValue(mdzx.getBtyBrandIdView());
        cell21.setCellStyle(header);

        SXSSFCell cell22 = row2.createCell(2);
        cell22.setCellStyle(header);
        SXSSFCell cell23 = row2.createCell(3);
        cell23.setCellStyle(header);


        SXSSFRow row3 = sheet.createRow(2);
        SXSSFCell cell30 = row3.createCell(0);
        //设置每一列的字段名
        cell30.setCellValue("总面积(平米)");
        cell30.setCellStyle(header);
        CellRangeAddress region31 = new CellRangeAddress(firstRow + 1, firstRow + 1, 1, 3);
        sheet.addMergedRegion(region31);

        SXSSFCell cell31 = row3.createCell(1);
        //设置每一列的字段名
        cell31.setCellValue(mdzx.getMianji());
        cell31.setCellStyle(header);

        SXSSFCell cell32 = row3.createCell(2);
        cell32.setCellStyle(header);
        SXSSFCell cell33 = row3.createCell(3);
        cell33.setCellStyle(header);

        SXSSFRow row4 = sheet.createRow(3);
        SXSSFCell cell40 = row4.createCell(0);
        //设置每一列的字段名--是预算总计，不是预计投资字段
        cell40.setCellValue("预估(元)");
        cell40.setCellStyle(header);
        CellRangeAddress region41 = new CellRangeAddress(firstRow + 2, firstRow + 2, 1, 3);
        sheet.addMergedRegion(region41);
        SXSSFCell cell41 = row4.createCell(1);
        //预算总计
        cell41.setCellValue(mdzx.getYujiTouzi() == null ? BigDecimal.ZERO.toString() : mdzx.getYujiTouzi().toString());
        cell41.setCellStyle(header);

        SXSSFCell cell42 = row4.createCell(2);
        cell42.setCellStyle(header);

        SXSSFCell cell43 = row4.createCell(3);
        cell43.setCellStyle(header);

        //TODO-4 设置内容标题
        //内容的标题所在行
        int concentitleStartRow = 6;
        //设置表头样式
        ExcelFormatUtil.initContentTitleEX(sheet, header, concentitleStartRow, titles, ints);
        logger.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");

        //TODO-5 从第contentStartRow行开始为内容数据
        int contentStartRow = concentitleStartRow + 1;
        if (list != null && list.size() > 0) {
            logger.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
            for (int i = 0; i < list.size(); i++) {
                ZxTzqkViewResult result = list.get(i);

                SXSSFRow row = sheet.createRow(contentStartRow + i - 1);
                int j = 0;

                // 科目
                SXSSFCell cell = row.createCell(j++);
                cell.setCellValue(result.getFirstLevelName());
                cell.setCellStyle(content);

                // 二级科目
                cell = row.createCell(j++);
                cell.setCellValue(result.getSecondLevelName());
                cell.setCellStyle(content);

                // 金额
                cell = row.createCell(j++);
                cell.setCellValue(result.getJine() == null ? BigDecimal.ZERO.toString() : result.getJine().toString());
                cell.setCellStyle(content);

                // 备注
                cell = row.createCell(j++);
                cell.setCellValue(result.getContent());
                cell.setCellStyle(content);

            }
            logger.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
        }

        //TODO 制表人、时间
        //所在行
        int sumRowNum = contentStartRow + list.size();
        SXSSFRow rowEnd = sheet.createRow(sumRowNum + 1);
        //制表人
        SXSSFCell cellEnd0 = rowEnd.createCell(0);
        cellEnd0.setCellValue("制表人：" + LoginContextHolder.getContext().getUser().getName());
        //制表时间
        SXSSFCell cellEnd1 = rowEnd.createCell(titles.length - 1);
        cellEnd1.setCellValue(DateUtil.getNow());

        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null) {
                        inputStream1.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return inputStream1;
    }


    @Override
    public List<ZxTzqkViewResult> getInvestmentSituation(Long btyZxMdzxId) {

        //TODO-1 要导出的数据内容
        List<ZxTzqkViewResult> list = new ArrayList<>();
        Mdzx mdzx = this.baseMapper.selectById(btyZxMdzxId);
        //查询所有的一级已经录入的成本
        List<ZxTzqkViewResult> yijiTzResultList = this.baseMapper.selectAllTzqkYiji(btyZxMdzxId);
        //查询所有的二级已经录入的成本
        List<ZxTzqkViewResult> erjiTzResultLsit = this.baseMapper.selectAllTzqkErji(btyZxMdzxId);
        //获取所有的一级科目-全
        List<ZxTzqkViewResult> zxKemuResultList1 = zxKemuMapper.selectAllYijiKemu("1");
        //获取所有的二级科目-全
        List<ZxTzqkViewResult> zxKemuResultList2 = zxKemuMapper.selectAllErjiKemu("2");

        //所有的一级
        for (ZxTzqkViewResult yijiKemu : zxKemuResultList1) {
            for (ZxTzqkViewResult data : yijiTzResultList) {
                if (data.getFirstLevelId() != null) {
                    if (data.getFirstLevelId().equals(yijiKemu.getFirstLevelId())) {
                        yijiKemu.setFirstLevelId(data.getFirstLevelId());
                        yijiKemu.setBtyZxMdzxId(data.getBtyZxMdzxId());
                        yijiKemu.setContent(data.getContent());
                        yijiKemu.setJine(data.getJine());
                        yijiKemu.setName(data.getName());
                    }
                }
            }
        }

        //所有的二级
        for (ZxTzqkViewResult erjiKemu : zxKemuResultList2) {
            for (ZxTzqkViewResult data : erjiTzResultLsit) {
                if (data.getSecondLevelId() != null) {
                    if (data.getSecondLevelId().equals(erjiKemu.getSecondLevelId())) {
                        erjiKemu.setFirstLevelId(data.getFirstLevelId());
                        erjiKemu.setBtyZxMdzxId(data.getBtyZxMdzxId());
                        erjiKemu.setContent(data.getContent());
                        erjiKemu.setJine(data.getJine());
                        erjiKemu.setName(data.getName());
                    }
                }
            }
        }

        BigDecimal sum = BigDecimal.ZERO;
        //在输出内容中加入一级科目汇总
        for (ZxTzqkViewResult yijiData : zxKemuResultList1) {
            sum = sum.add(yijiData.getJine() == null ? BigDecimal.ZERO : yijiData.getJine());
            yijiData.setFirstLevelName(yijiData.getName());
            list.add(yijiData);
            for (ZxTzqkViewResult erjiData : zxKemuResultList2) {
                if (erjiData.getFirstLevelId().equals(yijiData.getFirstLevelId())) {
                    erjiData.setSecondLevelName(erjiData.getName());
                    list.add(erjiData);
                }
            }
        }

        //总价
        ZxTzqkViewResult result = new ZxTzqkViewResult();
        result.setFirstLevelName("总计");
        //成本合计
        result.setJine(sum);
        list.add(result);
        //总投资
        ZxTzqkViewResult result1 = new ZxTzqkViewResult();
        result1.setSecondLevelName("总投资");
        result1.setJine(mdzx.getYujiTouzi());
        list.add(result1);
        //投资剩余
        ZxTzqkViewResult result2 = new ZxTzqkViewResult();
        result2.setSecondLevelName("投资剩余");
        result2.setJine(mdzx.getTouzishengyu());
        list.add(result2);
        return list;
    }

    @Override
    public List<ZxTzqkViewResult> getTzqk(Long btyZxMdzxId) {
        //TODO-1 要导出的数据内容
        List<ZxTzqkViewResult> list = new ArrayList<>();
        Mdzx mdzx = this.baseMapper.selectById(btyZxMdzxId);
        //获取所有的一级科目-全
        List<ZxTzqkViewResult> zxKemuResultList1 = zxKemuMapper.selectAllYijiKemu("1");
        //获取所有的二级科目-全
        List<ZxTzqkViewResult> zxKemuResultList2 = zxKemuMapper.selectAllErjiKemu("2");
        //查找出当前店的所有投资情况记录
        ZxTzqkParam param = new ZxTzqkParam();
        param.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        List<ZxTzqkResult> zxTzqkResults = zxTzqkMapper.customList(param);
        //TODO-2 将所有的投资情况记录，放入二级科目中
        if (CollectionUtil.isNotEmpty(zxTzqkResults)) {
            for (ZxTzqkResult tzqkResult : zxTzqkResults) {
                if (tzqkResult.getFirstLevelId() != null && tzqkResult.getSecondLevelId() != null) {
                    //为二级科目放入指定内容
                    for (ZxTzqkViewResult erjiData : zxKemuResultList2) {
                        if (tzqkResult.getFirstLevelId() != null
                                && tzqkResult.getSecondLevelId() != null
                                && tzqkResult.getFirstLevelId().equals(erjiData.getFirstLevelId())
                                && tzqkResult.getSecondLevelId().equals(erjiData.getSecondLevelId())) {
                            erjiData.setJine(tzqkResult.getJine());
                            erjiData.setContent(tzqkResult.getContent());
                            //System.out.println(tzqkResult.getContent());
                            erjiData.setBeiwang(tzqkResult.getBeiwang());
                            //公式
                            erjiData.setFormula(tzqkResult.getFormula());
                        }
                    }
                }
//                else {
//                    //为一级科目放入金额
//                    for (ZxTzqkViewResult yijiData : zxKemuResultList1) {
//                        if (tzqkResult.getFirstLevelId().equals(yijiData.getFirstLevelId())) {
//                            yijiData.setJine(BigDecimal.ZERO);
//                        }
//
//                    }
//                }

            }
        }
        BigDecimal sum = BigDecimal.ZERO;
        //TODO-3 在输出内容中加入一级科目汇总，必须先放一级再放二级，保证tzqk列表显示顺序
        for (ZxTzqkViewResult yijiData : zxKemuResultList1) {
            BigDecimal sumYiJi = BigDecimal.ZERO;
            //先放入该一级科目保证显示顺序，随后赋值，值照样改变，引用对象是同一个
            list.add(yijiData);
            for (ZxTzqkViewResult erjiData : zxKemuResultList2) {
                erjiData.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
                if (erjiData.getFirstLevelId().equals(yijiData.getFirstLevelId())) {
                    erjiData.setSecondLevelName(erjiData.getName());
                    list.add(erjiData);
                    sumYiJi = sumYiJi.add(erjiData.getJine() == null ? BigDecimal.ZERO : erjiData.getJine());
                }
            }
            yijiData.setJine(sumYiJi);
            yijiData.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
            sum = sum.add(yijiData.getJine() == null ? BigDecimal.ZERO : yijiData.getJine());
            yijiData.setFirstLevelName(yijiData.getName());
        }

        DecimalFormat decimalformat = new DecimalFormat("0.00%");

        //TODO-4.1 占比之和保证为1
        Map<String, Double> lingData = new HashMap<>();
        Map<String, Double> notLingData = new HashMap<>();

        //TODO-4.2 占比=一级科目金额/总金额
        Double sumZhanBi = 0d;

        for (ZxTzqkViewResult kemuData : list) {
            //一级科目
            if (!StringUtils.isEmpty(kemuData.getFirstLevelName())) {
                //合计为0或者一级科目金额为0，占比为0
                if (sum.compareTo(BigDecimal.ZERO) == 0 || kemuData.getJine().compareTo(BigDecimal.ZERO) == 0) {
                    kemuData.setPercentage(decimalformat.format(0));
                    lingData.put(kemuData.getFirstLevelId() + kemuData.getFirstLevelName(), 0d);
                    continue;
                }
                //占比
                double per = kemuData.getJine().divide(sum, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
                notLingData.put(kemuData.getFirstLevelId() + kemuData.getFirstLevelName(), per);
                sumZhanBi = sumZhanBi + per;
                kemuData.setPercentage(decimalformat.format(per));
            }
        }

        //TODO-4.3 占比之和保证为1
        if (sumZhanBi != 1) {
            if (notLingData.size() > 0) {
                //如果就一个值大于0，将其值置为1
                if (notLingData.size() == 1) {
                    for (Map.Entry<String, Double> m : notLingData.entrySet()) {
                        notLingData.put(m.getKey(), 1d);
                        //改变对应的值
                        this.resetPercentage(list, m.getKey(), 1d);
                    }
                }
                //如果为多个值，值之和必须为1
                if (notLingData.size() >= 2) {
                    //和小于1，把差值补给第一个值
                    if (sumZhanBi < 1) {
                        double chazhi = 1 - sumZhanBi;
                        for (Map.Entry<String, Double> m : notLingData.entrySet()) {
                            Double value = m.getValue();
                            notLingData.put(m.getKey(), value + chazhi);
                            //改变对应的值
                            this.resetPercentage(list, m.getKey(), value + chazhi);
                            break;
                        }
                    }
                    //和大于1，把差值在第一个值减去
                    if (sumZhanBi > 1) {
                        double chazhi = sumZhanBi - 1;
                        for (Map.Entry<String, Double> m : notLingData.entrySet()) {
                            Double value = m.getValue();
                            notLingData.put(m.getKey(), value - chazhi);
                            //改变对应的值
                            this.resetPercentage(list, m.getKey(), value - chazhi);
                            break;
                        }
                    }
                }
            }
        }

        //总价
        ZxTzqkViewResult result = new ZxTzqkViewResult();
        result.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        //成本合计
        result.setFirstLevelName("总计");
        result.setJine(sum);
        list.add(result);
        //总投资
        ZxTzqkViewResult result1 = new ZxTzqkViewResult();
        result1.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        result1.setSecondLevelName("总投资");
        result1.setJine(mdzx.getYujiTouzi());
        list.add(result1);
        //投资剩余
        ZxTzqkViewResult result2 = new ZxTzqkViewResult();
        result2.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        result2.setSecondLevelName("投资剩余");
        result2.setJine(mdzx.getTouzishengyu());
        list.add(result2);
        return list;
    }

    /**
     * 重置对应的一个一级科目的占比值
     *
     * @param list
     * @param key
     * @param percentage
     */
    private void resetPercentage(List<ZxTzqkViewResult> list, String key, Double percentage) {
        DecimalFormat decimalformat = new DecimalFormat("0.00%");
        for (ZxTzqkViewResult kemuData : list) {
            //只针对一级科目
            if (!StringUtils.isEmpty(kemuData.getFirstLevelName())) {
                if ((kemuData.getFirstLevelId() + kemuData.getFirstLevelName()).equals(key)) {
                    kemuData.setPercentage(decimalformat.format(percentage));
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData copyZx(MdzxParam old) {
        //新建mdzx
        MdzxParam mdzx = new MdzxParam();
        mdzx.setCreateUser(LoginContextHolder.getContext().getUserId());
        mdzx.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        mdzx.setDelFlag(0);
        mdzx.setCreateTime(new Date());
        mdzx.setMianji(old.getMianji());
        mdzx.setYujiTouzi(old.getYujiTouzi());
        mdzx.setYusuanHeji(old.getYusuanHeji());
        mdzx.setChengbenHeji(old.getChengbenHeji());
        mdzx.setTouzishengyu(old.getTouzishengyu());
        Mdzx entity = getEntity(mdzx);

        boolean save = this.save(entity);
        if (save) {
            //复制预算
            List<ZxYusuanResult> paramlist = zxYusuanMapper.listYusuanInfoBymdzx(old.getBtyZxMdzxId());
            if (ToolUtil.isNotEmpty(paramlist)) {
                List<ZxYusuan> yusuanlist = new ArrayList<>();
                for (ZxYusuanResult param : paramlist) {
                    ZxYusuan ys = new ZxYusuan();
                    ys.setXuhao(param.getXuhao());
                    ys.setXiangmu(param.getXiangmu());
                    ys.setJine(param.getJine());
                    ys.setBtyZxMdzxId(entity.getBtyZxMdzxId());
                    ys.setCreateUser(LoginContextHolder.getContext().getUserId());
                    ys.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                    ys.setCreateTime(new Date());
                    yusuanlist.add(ys);
                }
                boolean b = zxYusuanMapper.batchAdd(yusuanlist);
                if (!b) {
                    logger.error("复制预算数据失败!");
                    throw new BusException(BusExceptionEnum.ERR_COPY_YUSUAN);
                }

            }

            //复制成本  by zwf 成本不用复制
            /*
            List<ZxChengbenResult> cblist = zxChengbenMapper.listChengbenInfoBymdzx(old.getBtyZxMdzxId());
            if (ToolUtil.isNotEmpty(cblist)) {
                List<ZxChengben> chengbenlist = new ArrayList<>();
                for (ZxChengbenResult param : cblist) {
                    ZxChengben cb = new ZxChengben();
                    cb.setBtyZxMdzxId(entity.getBtyZxMdzxId());
                    cb.setBtyyBxdaId(param.getBtyyBxdaId());
                    cb.setBtyyBxdaIdView(param.getBtyyBxdaIdView());
                    cb.setBtyZxHuopinId(param.getBtyZxHuopinId());
                    cb.setBtyZxHuopinIdView(param.getBtyZxHuopinIdView());
                    cb.setDanwei(param.getDanwei());
                    cb.setChicun(param.getChicun());
                    cb.setShuliang(param.getShuliang());
                    cb.setJiage(param.getJiage());
                    cb.setZongjia(param.getZongjia());

                    cb.setCreateUser(LoginContextHolder.getContext().getUserId());
                    cb.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                    cb.setCreateTime(new Date());
                    chengbenlist.add(cb);
                }
                boolean b2 = zxChengbenMapper.batchAdd(chengbenlist);
                if (!b2) {
                    logger.error("复制成本数据失败!");
                    throw new BusException(BusExceptionEnum.ERR_COPY_CHENGBEN);
                }
            }
            */
            return ResponseData.success(entity);
        } else {
            throw new BusException(BusExceptionEnum.ERR_COPY_MDZX);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData copyZxYuSuan(MdzxParam targetParam) {
        Mdzx old = this.getById(targetParam.getCopiedBtyZxMdzxId());
        //新建mdzx
        MdzxParam mdzx = new MdzxParam();
        mdzx.setCreateUser(LoginContextHolder.getContext().getUserId());
        mdzx.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        mdzx.setDelFlag(0);
        mdzx.setCreateTime(new Date());
        mdzx.setMianji(old.getMianji());
        mdzx.setYujiTouzi(old.getYujiTouzi());
        mdzx.setYusuanHeji(old.getYusuanHeji());
        mdzx.setChengbenHeji(old.getChengbenHeji());
        mdzx.setTouzishengyu(old.getTouzishengyu());

        //选择了门店，以选择的门店为准
        if (targetParam.getBtyBrandId() != 0) {
            //选择了门店，门店名称以选择的门店为准
            Project project = projectMapper.selectById(targetParam.getBtyBrandId());
            if (project != null) {
                mdzx.setBtyBrandIdView(project.getName());
            }
            mdzx.setBtyBrandId(targetParam.getBtyBrandId());
        }

        //没有选择门店，以输入的门店名称为准
        if (targetParam.getBtyBrandId() == 0 && !"".equals(targetParam.getBtyBrandIdView())) {
            //没有选择门店，以输入的门店名为准
            QueryWrapper<Mdzx> wrapper = new QueryWrapper<>();
            wrapper = wrapper.eq("bty_brand_id_view", targetParam.getBtyBrandIdView());
            wrapper = wrapper.eq("del_flag", 0);
            List<Mdzx> data = this.baseMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(data)) {
                return new ErrorResponseData("复制失败，门店名称已存在，同一门店只能添加一次");
            }
            mdzx.setBtyBrandIdView(targetParam.getBtyBrandIdView());
        }


        Mdzx entity = getEntity(mdzx);

        boolean save = this.save(entity);
        if (save) {
            //复制预算
            List<ZxYusuanResult> paramlist = zxYusuanMapper.listYusuanInfoBymdzx(old.getBtyZxMdzxId());
            if (ToolUtil.isNotEmpty(paramlist)) {
                List<ZxYusuan> yusuanlist = new ArrayList<>();
                for (ZxYusuanResult param : paramlist) {
                    ZxYusuan ys = new ZxYusuan();
                    ys.setXuhao(param.getXuhao());
                    ys.setXiangmu(param.getXiangmu());
                    ys.setJine(param.getJine());
                    ys.setBtyZxMdzxId(entity.getBtyZxMdzxId());
                    ys.setCreateUser(LoginContextHolder.getContext().getUserId());
                    ys.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                    ys.setCreateTime(new Date());
                    yusuanlist.add(ys);
                }
                boolean b = zxYusuanMapper.batchAdd(yusuanlist);
                if (!b) {
                    logger.error("复制预算数据失败!");
                    throw new BusException(BusExceptionEnum.ERR_COPY_YUSUAN);
                }

            }

            //复制成本  by zwf 成本不用复制
            /*
            List<ZxChengbenResult> cblist = zxChengbenMapper.listChengbenInfoBymdzx(old.getBtyZxMdzxId());
            if (ToolUtil.isNotEmpty(cblist)) {
                List<ZxChengben> chengbenlist = new ArrayList<>();
                for (ZxChengbenResult param : cblist) {
                    ZxChengben cb = new ZxChengben();
                    cb.setBtyZxMdzxId(entity.getBtyZxMdzxId());
                    cb.setBtyyBxdaId(param.getBtyyBxdaId());
                    cb.setBtyyBxdaIdView(param.getBtyyBxdaIdView());
                    cb.setBtyZxHuopinId(param.getBtyZxHuopinId());
                    cb.setBtyZxHuopinIdView(param.getBtyZxHuopinIdView());
                    cb.setDanwei(param.getDanwei());
                    cb.setChicun(param.getChicun());
                    cb.setShuliang(param.getShuliang());
                    cb.setJiage(param.getJiage());
                    cb.setZongjia(param.getZongjia());

                    cb.setCreateUser(LoginContextHolder.getContext().getUserId());
                    cb.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                    cb.setCreateTime(new Date());
                    chengbenlist.add(cb);
                }
                boolean b2 = zxChengbenMapper.batchAdd(chengbenlist);
                if (!b2) {
                    logger.error("复制成本数据失败!");
                    throw new BusException(BusExceptionEnum.ERR_COPY_CHENGBEN);
                }
            }
            */
            return ResponseData.success(entity);
        } else {
            throw new BusException(BusExceptionEnum.ERR_COPY_MDZX);
        }
    }


    /**
     * 获取map列表
     *
     * @author jiangge
     * @Date 2020-11-02
     */
    @Override
    public List<Map<String, Object>> mdzxList(MdzxParam paramCondition) {

        if (paramCondition.getBtyZxChengbenId() != null && !paramCondition.getBtyZxChengbenId().equals(0)) {
            ZxChengben chengben = zxChengbenMapper.selectById(paramCondition.getBtyZxChengbenId());
            if (chengben != null && chengben.getBtyZxMdzxId() != null) {
                paramCondition.setBtyZxMdzxId(chengben.getBtyZxMdzxId());
            }
        }

        return this.baseMapper.customMapList(paramCondition);
    }

    @Override
    public List<Map<String, Object>> ghsList(MdzxParam paramCondition) {

        if (paramCondition.getBtyZxChengbenId() != null && !paramCondition.getBtyZxChengbenId().equals(0)) {
            ZxChengben chengben = zxChengbenMapper.selectById(paramCondition.getBtyZxChengbenId());
            if (chengben != null && chengben.getBtyZxMdzxId() != null) {
                paramCondition.setBtyZxMdzxId(chengben.getBtyZxMdzxId());
            }
        }

        return this.baseMapper.ghsMapList(paramCondition);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData copyYusn(MdzxParam param) {

        //查询该店名是否存在
        int con = baseMapper.getName(param.getBtyBrandIdView());
        if (con > 0){
            return ResponseData.error("该店名已存在，不可提交。");
        }

        //增加装修记录
        //选择了门店，门店名称以选择的门店为准

        //是否需要添加装修记录
        boolean flag = true;
        Long mdid = null;
        if (param.getBtyBrandId() != 0) {
            //同一个店不能添加两次
            QueryWrapper<Mdzx> wrapper = new QueryWrapper<>();
            wrapper = wrapper.eq("bty_brand_id", param.getBtyBrandId());
            wrapper = wrapper.eq("del_flag", 0);
            List<Mdzx> data = this.baseMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(data)) {
                //已经存在无须添加
                if (data.get(0).getYusuanLock() == 1) {
                    return new ErrorResponseData("复制失败，此店数据已经被锁定，如需操作，请先解锁");
                }

                flag = false;
                mdid = data.get(0).getBtyZxMdzxId();
            }
            //选择了门店，门店名称以选择的门店为准
//            Project project = projectMapper.selectById(param.getBtyBrandId());
//            param.setBtyBrandIdView(project.getName());
        }

        //没有选择门店，以输入的门店名称为准
        if (param.getBtyBrandId() == 0 && !"".equals(param.getBtyBrandIdView())) {
            //没有选择门店，以输入的门店名为准
            QueryWrapper<Mdzx> wrapper = new QueryWrapper<>();
            wrapper = wrapper.eq("bty_brand_id_view", param.getBtyBrandIdView());
            wrapper = wrapper.eq("del_flag", 0);
            List<Mdzx> data = this.baseMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(data)) {
                flag = false;
                mdid = data.get(0).getBtyZxMdzxId();
            }
        }

        //门店助记码
        String pinInCode = PinYinUtil.getPinYinCode(param.getBtyBrandIdView());
        param.setMdZhujima(pinInCode);
        param.setCreateUser(LoginContextHolder.getContext().getUserId());
        param.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        param.setDelFlag(0);
        //负责人
        Mdzx entity = getEntity(param);
        if (flag == true) {
            //门店名同步到工程表
            if (entity.getMdBianma() != null && !entity.getMdBianma().equals("")) {
                QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("yaoma", entity.getMdBianma());
                Project project = projectMapper.selectOne(queryWrapper);
                if (project != null) {
                    project.setName(entity.getBtyBrandIdView());
                    projectMapper.updateById(project);
                }
            }

        }
        this.save(entity);

        //复制预算模板
        List<ZxYusuanResult> paramlist = zxYusuanMapper.listYusuantemplateByPinpai(param.getPinpai());

        if (ToolUtil.isNotEmpty(paramlist)) {
            List<ZxYusuan> yusuanlist = new ArrayList<>();
            for (ZxYusuanResult param1 : paramlist) {
                ZxYusuan ys = new ZxYusuan();
                ys.setXuhao(param1.getXuhao());
                ys.setXiangmu(param1.getXiangmu());
                ys.setJine(param1.getJine());
                if (flag == true) {
                    ys.setBtyZxMdzxId(entity.getBtyZxMdzxId());
                } else {
                    ys.setBtyZxMdzxId(mdid);
                }
                ys.setCreateUser(LoginContextHolder.getContext().getUserId());
                ys.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                ys.setCreateTime(new Date());
                yusuanlist.add(ys);
            }
            boolean b = zxYusuanMapper.batchAdd(yusuanlist);
            if (!b) {
                logger.error("复制预算数据失败!");
                throw new BusException(BusExceptionEnum.ERR_COPY_YUSUAN);
            }

        }


        return ResponseData.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData editYujiTouzi(MdzxParam param) {
        //如果预算数据已经锁定，不允许需改
        Mdzx mdzx = this.baseMapper.selectById(param.getBtyZxMdzxId());
        if (mdzx.getYusuanLock() == 1) {
            return new ErrorResponseData("预算总计设置失败，此店数据已经被锁定，如需操作，请先解锁");
        }
        updateByParam(param);
        calculateChengbenAndYusuan(param.getBtyZxMdzxId(), BigDecimal.ZERO);
        return ResponseData.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData yusuanLockEdit(MdzxParam param) {
        Mdzx mdzx = this.getById(param.getBtyZxMdzxId());
        //锁定
        if (param.getYusuanLock() == 1) {
            if (mdzx.getYusuanLock() == 1) {
                return new ErrorResponseData("锁定失败，请不要重复锁定");
            }
        }

        //解锁
        if (param.getYusuanLock() == 0) {
            if (mdzx.getYusuanLock() == 0) {
                return new ErrorResponseData("解锁失败，数据未被锁定，无须解锁");
            }
            if (!mdzx.getYusuanLockPass().equals(param.getYusuanLockPass())) {
                return new ErrorResponseData("解锁失败，密码错误");
            }
        }

        //更新状态
        updateByParam(param);
        return ResponseData.success();
    }


    @Override
    public ResponseEntity<byte[]> exportExcel2(HttpServletRequest request, HttpServletResponse response, Long btyZxMdzxId) {
        try {
            logger.info(">>>>>>>>>>开始导出excel>>>>>>>>>>");
            //TODO-1 要导出的数据内容
            List<ZxTzqkViewResult> list = this.getTzqk(btyZxMdzxId);
            BaseFrontController baseFrontController = new BaseFrontController();
            //文件名称
            Mdzx mdzx = this.baseMapper.selectById(btyZxMdzxId);
            return baseFrontController.buildResponseEntity(export2(list, mdzx), mdzx.getBtyBrandIdView() + ".xls");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(">>>>>>>>>>导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }


    private InputStream export2(List<ZxTzqkViewResult> list, Mdzx mdzx) {
        logger.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        // 保留1000条数据在内存中
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet();
        // 设置报表头样式cell样式
        CellStyle header = ExcelFormatUtil.headSytle(wb);
        // 报表体样式
        CellStyle content = ExcelFormatUtil.contentStyle(wb);

        //TODO-2 每一列字段名
        String[] titles = new String[]{"一级科目", "二级科目", "金额", "占比", "备注"};

        // 字段名所在表格的宽度，数量应与列字段名数量一致
        int[] ints = new int[]{5000, 5000, 5000, 5000, 5000};


        //TODO-3 设置总标题内容，没有可略过
        //设置第一行标题：指定 4 个参数，起始行，结束行，起始列，结束列,
        int firstRow = 1;
        int lastRow = 1;
        int firstCol = 1;
        int lastCol = ints.length;
        SXSSFRow row1 = sheet.createRow(0);
        SXSSFCell cell0 = row1.createCell(0);
        CellRangeAddress regionFist = new CellRangeAddress(firstRow - 1, lastRow - 1, firstCol - 1, lastCol - 1);
        sheet.addMergedRegion(regionFist);
        //设置每一列的字段名
        cell0.setCellValue("投资情况表");
        cell0.setCellStyle(header);

        SXSSFRow row2 = sheet.createRow(1);
        SXSSFCell cell20 = row2.createCell(0);
        //设置每一列的字段名
        cell20.setCellValue("店名");
        cell20.setCellStyle(header);

        CellRangeAddress region21 = new CellRangeAddress(firstRow, firstRow, 1, lastCol - 1);
        sheet.addMergedRegion(region21);

        SXSSFCell cell21 = row2.createCell(1);
        //设置每一列的字段名
        cell21.setCellValue(mdzx.getBtyBrandIdView());
        cell21.setCellStyle(header);

        SXSSFCell cell22 = row2.createCell(2);
        cell22.setCellStyle(header);
        SXSSFCell cell23 = row2.createCell(3);
        cell23.setCellStyle(header);
        SXSSFCell cell24 = row2.createCell(4);
        cell24.setCellStyle(header);


        SXSSFRow row3 = sheet.createRow(2);
        SXSSFCell cell30 = row3.createCell(0);
        //设置每一列的字段名
        cell30.setCellValue("总面积(平米)");
        cell30.setCellStyle(header);
        CellRangeAddress region31 = new CellRangeAddress(firstRow + 1, firstRow + 1, 1, lastCol - 1);
        sheet.addMergedRegion(region31);

        SXSSFCell cell31 = row3.createCell(1);
        //设置每一列的字段名
        cell31.setCellValue(mdzx.getMianji());
        cell31.setCellStyle(header);

        SXSSFCell cell32 = row3.createCell(2);
        cell32.setCellStyle(header);
        SXSSFCell cell33 = row3.createCell(3);
        cell33.setCellStyle(header);
        SXSSFCell cell34 = row3.createCell(4);
        cell34.setCellStyle(header);

        SXSSFRow row4 = sheet.createRow(3);
        SXSSFCell cell40 = row4.createCell(0);
        //设置每一列的字段名--是预算总计，不是预计投资字段
        cell40.setCellValue("预估(元)");
        cell40.setCellStyle(header);
        CellRangeAddress region41 = new CellRangeAddress(firstRow + 2, firstRow + 2, 1, lastCol - 1);
        sheet.addMergedRegion(region41);
        SXSSFCell cell41 = row4.createCell(1);
        //预算总计
        cell41.setCellValue(mdzx.getYujiTouzi() == null ? BigDecimal.ZERO.toString() : mdzx.getYujiTouzi().toString());
        cell41.setCellStyle(header);

        SXSSFCell cell42 = row4.createCell(2);
        cell42.setCellStyle(header);

        SXSSFCell cell43 = row4.createCell(3);
        cell43.setCellStyle(header);
        SXSSFCell cell44 = row4.createCell(4);
        cell44.setCellStyle(header);

        //单位预估占比
        SXSSFRow row5 = sheet.createRow(4);
        SXSSFCell cell50 = row5.createCell(0);
        //设置每一列的字段名--是预算总计，不是预计投资字段
        cell50.setCellValue("单位面积预估(单位：元)");
        cell50.setCellStyle(header);
        CellRangeAddress region51 = new CellRangeAddress(firstRow + 3, firstRow + 3, 1, lastCol - 1);
        sheet.addMergedRegion(region51);
        SXSSFCell cell51 = row5.createCell(1);

        //计算单位面积预估值
        BigDecimal unitYusuanHeji = BigDecimal.ZERO;
        if (mdzx.getYujiTouzi().compareTo(BigDecimal.ZERO) != 0 && !StringUtils.isEmpty(mdzx.getMianji())) {
            unitYusuanHeji = mdzx.getYujiTouzi().divide(new BigDecimal(mdzx.getMianji()), 2, BigDecimal.ROUND_UP);
        }

        //单位面积预估
        cell51.setCellValue(unitYusuanHeji.toString());
        cell51.setCellStyle(header);

        SXSSFCell cell52 = row5.createCell(2);
        cell52.setCellStyle(header);

        SXSSFCell cell53 = row5.createCell(3);
        cell53.setCellStyle(header);
        SXSSFCell cell54 = row5.createCell(4);
        cell54.setCellStyle(header);

        //TODO-4 设置内容标题
        //内容的标题所在行
        int concentitleStartRow = 7;
        //设置表头样式
        ExcelFormatUtil.initContentTitleEX(sheet, header, concentitleStartRow, titles, ints);
        logger.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");

        //TODO-5 从第contentStartRow行开始为内容数据
        int contentStartRow = concentitleStartRow + 1;
        if (list != null && list.size() > 0) {
            logger.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
            for (int i = 0; i < list.size(); i++) {
                ZxTzqkViewResult result = list.get(i);

                SXSSFRow row = sheet.createRow(contentStartRow + i - 1);
                int j = 0;

                // 科目
                SXSSFCell cell = row.createCell(j++);
                cell.setCellValue(result.getFirstLevelName());
                cell.setCellStyle(content);

                // 二级科目
                cell = row.createCell(j++);
                cell.setCellValue(result.getSecondLevelName());
                cell.setCellStyle(content);

                // 金额
                cell = row.createCell(j++);
                cell.setCellValue(result.getJine() == null ? BigDecimal.ZERO.toString() : result.getJine().toString());
                cell.setCellStyle(content);

                //占比
                cell = row.createCell(j++);
                cell.setCellValue(result.getPercentage());
                cell.setCellStyle(content);

                // 备注
                cell = row.createCell(j++);
                cell.setCellValue(result.getContent());
                cell.setCellStyle(content);

            }
            logger.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
        }

        //TODO 制表人、时间
        //所在行
        int sumRowNum = contentStartRow + list.size();
        SXSSFRow rowEnd = sheet.createRow(sumRowNum + 1);
        //制表人
        SXSSFCell cellEnd0 = rowEnd.createCell(0);
        cellEnd0.setCellValue("制表人：" + LoginContextHolder.getContext().getUser().getName());
        //制表时间
        SXSSFCell cellEnd1 = rowEnd.createCell(titles.length - 1);
        cellEnd1.setCellValue(DateUtil.getNow());

        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null) {
                        inputStream1.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return inputStream1;
    }

    @Override
    public ResponseEntity<byte[]> exportExcelWithGongshi(HttpServletRequest request, HttpServletResponse response, Long btyZxMdzxId) {
        try {
            logger.info(">>>>>>>>>>开始导出excel>>>>>>>>>>");
            //TODO-1 要导出的数据内容
            List<ZxTzqkViewResult> list = this.getTzqk(btyZxMdzxId);
            BaseFrontController baseFrontController = new BaseFrontController();
            //文件名称
            Mdzx mdzx = this.baseMapper.selectById(btyZxMdzxId);
            return baseFrontController.buildResponseEntity(exportWithGongshi(list, mdzx), mdzx.getBtyBrandIdView() + ".xls");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(">>>>>>>>>>导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }

    /**
     * 带公式的导出
     *
     * @param list
     * @param mdzx
     * @return
     */
    private InputStream exportWithGongshi(List<ZxTzqkViewResult> list, Mdzx mdzx) {
        logger.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        // 保留1000条数据在内存中
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet();
        // 设置报表头样式cell样式
        CellStyle header = ExcelFormatUtil.headSytle(wb);
        // 报表体样式
        CellStyle content = ExcelFormatUtil.contentStyle(wb);

        //TODO-2 每一列字段名
        String[] titles = new String[]{"一级科目", "二级科目", "金额", "公式", "备注"};

        // 字段名所在表格的宽度，数量应与列字段名数量一致
        int[] ints = new int[]{5000, 5000, 5000, 5000, 5000};


        //TODO-3 设置总标题内容，没有可略过
        //设置第一行标题：指定 4 个参数，起始行，结束行，起始列，结束列,
        int firstRow = 1;
        int lastRow = 1;
        int firstCol = 1;
        int lastCol = 5;
        SXSSFRow row1 = sheet.createRow(0);
        SXSSFCell cell0 = row1.createCell(0);
        CellRangeAddress regionFist = new CellRangeAddress(firstRow - 1, lastRow - 1, firstCol - 1, lastCol - 1);
        sheet.addMergedRegion(regionFist);
        //设置每一列的字段名
        cell0.setCellValue("投资情况表");
        cell0.setCellStyle(header);

        SXSSFRow row2 = sheet.createRow(1);
        SXSSFCell cell20 = row2.createCell(0);
        //设置每一列的字段名
        cell20.setCellValue("店名");
        cell20.setCellStyle(header);

        CellRangeAddress region21 = new CellRangeAddress(firstRow, firstRow, 1, 4);
        sheet.addMergedRegion(region21);

        SXSSFCell cell21 = row2.createCell(1);
        //设置每一列的字段名
        cell21.setCellValue(mdzx.getBtyBrandIdView());
        cell21.setCellStyle(header);

        SXSSFCell cell22 = row2.createCell(2);
        cell22.setCellStyle(header);
        SXSSFCell cell23 = row2.createCell(3);
        cell23.setCellStyle(header);
        SXSSFCell cell24 = row2.createCell(4);
        cell24.setCellStyle(header);


        SXSSFRow row3 = sheet.createRow(2);
        SXSSFCell cell30 = row3.createCell(0);
        //设置每一列的字段名
        cell30.setCellValue("总面积(平米)");
        cell30.setCellStyle(header);
        CellRangeAddress region31 = new CellRangeAddress(firstRow + 1, firstRow + 1, 1, 4);
        sheet.addMergedRegion(region31);

        SXSSFCell cell31 = row3.createCell(1);
        //设置每一列的字段名
        cell31.setCellValue(mdzx.getMianji());
        cell31.setCellStyle(header);

        SXSSFCell cell32 = row3.createCell(2);
        cell32.setCellStyle(header);
        SXSSFCell cell33 = row3.createCell(3);
        cell33.setCellStyle(header);
        SXSSFCell cell34 = row3.createCell(4);
        cell34.setCellStyle(header);

        SXSSFRow row4 = sheet.createRow(3);
        SXSSFCell cell40 = row4.createCell(0);
        //设置每一列的字段名--是预算总计，不是预计投资字段
        cell40.setCellValue("预估(元)");
        cell40.setCellStyle(header);
        CellRangeAddress region41 = new CellRangeAddress(firstRow + 2, firstRow + 2, 1, 4);
        sheet.addMergedRegion(region41);
        SXSSFCell cell41 = row4.createCell(1);
        //预算总计
        cell41.setCellValue(mdzx.getYujiTouzi() == null ? BigDecimal.ZERO.toString() : mdzx.getYujiTouzi().toString());
        cell41.setCellStyle(header);

        SXSSFCell cell42 = row4.createCell(2);
        cell42.setCellStyle(header);

        SXSSFCell cell43 = row4.createCell(3);
        cell43.setCellStyle(header);

        SXSSFCell cell44 = row4.createCell(4);
        cell44.setCellStyle(header);

        //TODO-4 设置内容标题
        //内容的标题所在行
        int concentitleStartRow = 6;
        //设置表头样式
        ExcelFormatUtil.initContentTitleEX(sheet, header, concentitleStartRow, titles, ints);
        logger.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");

        //TODO-5 从第contentStartRow行开始为内容数据
        int contentStartRow = concentitleStartRow + 1;
        if (list != null && list.size() > 0) {
            logger.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
            for (int i = 0; i < list.size(); i++) {
                ZxTzqkViewResult result = list.get(i);

                SXSSFRow row = sheet.createRow(contentStartRow + i - 1);
                int j = 0;

                // 科目
                SXSSFCell cell = row.createCell(j++);
                cell.setCellValue(result.getFirstLevelName());
                cell.setCellStyle(content);

                // 二级科目
                cell = row.createCell(j++);
                cell.setCellValue(result.getSecondLevelName());
                cell.setCellStyle(content);

                // 金额
                cell = row.createCell(j++);
                cell.setCellValue(result.getJine() == null ? BigDecimal.ZERO.toString() : result.getJine().toString());
                cell.setCellStyle(content);

                // 公式
                cell = row.createCell(j++);
                cell.setCellValue(result.getFormula() == null ? "" : result.getFormula());
                cell.setCellStyle(content);

                // 备注
                cell = row.createCell(j++);
                cell.setCellValue(result.getContent());
                cell.setCellStyle(content);

            }
            logger.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
        }

        //TODO 制表人、时间
        //所在行
        int sumRowNum = contentStartRow + list.size();
        SXSSFRow rowEnd = sheet.createRow(sumRowNum + 1);
        //制表人
        SXSSFCell cellEnd0 = rowEnd.createCell(0);
        cellEnd0.setCellValue("制表人：" + LoginContextHolder.getContext().getUser().getName());
        //制表时间
        SXSSFCell cellEnd1 = rowEnd.createCell(titles.length - 1);
        cellEnd1.setCellValue(DateUtil.getNow());

        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null) {
                        inputStream1.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return inputStream1;
    }

    @Override
    public ResponseData lock(List<MdzxParam> params) {
        for (MdzxParam p : params) {
            updateByParam(p);
        }
        return ResponseData.success();
    }

    @Override
    public ResponseEntity<byte[]> exportMx(HttpServletRequest request, HttpServletResponse response, MdzxParam param) {
        try {
            Mdzx mdzx = getById(param.getBtyZxMdzxId());
            String fileName = (mdzx != null ? mdzx.getBtyBrandIdView() + "-甲供材明细" : "甲供材明细");
            //获取明细列表
            List<Map<String, Object>> mingxiList = this.baseMapper.listMingxiDetail(param);
            InputStream stream = exportHandler(mingxiList, fileName);
            return new BaseFrontController().buildResponseEntity(stream, fileName + ".xls");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("导出明细异常：{}", e.getMessage());
        }
        return null;
    }

    @Override
    public List<ZxTzqkViewResult> getTzqkDgd(Long btyZxMdzxId) {
        //TODO-1 要导出的数据内容
        List<ZxTzqkViewResult> list = new ArrayList<>();
        Mdzx mdzx = this.baseMapper.selectById(btyZxMdzxId);
        //获取所有的一级科目-全
        List<ZxTzqkViewResult> zxKemuResultList1 = zxKemuMapper.selectAllYijiKemuDgd("1");
        //获取所有的二级科目-全
        List<ZxTzqkViewResult> zxKemuResultList2 = zxKemuMapper.selectAllErjiKemuDgd("2");
        //查找出当前店的所有投资情况记录
        ZxTzqkParam param = new ZxTzqkParam();
        param.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        List<ZxTzqkResult> zxTzqkResults = zxTzqkMapper.customList(param);
        //TODO-2 将所有的投资情况记录，放入二级科目中
        if (CollectionUtil.isNotEmpty(zxTzqkResults)) {
            for (ZxTzqkResult tzqkResult : zxTzqkResults) {
                if (tzqkResult.getFirstLevelId() != null && tzqkResult.getSecondLevelId() != null) {
                    //为二级科目放入指定内容
                    for (ZxTzqkViewResult erjiData : zxKemuResultList2) {
                        if (tzqkResult.getFirstLevelId() != null
                                && tzqkResult.getSecondLevelId() != null
                                && tzqkResult.getFirstLevelId().equals(erjiData.getFirstLevelId())
                                && tzqkResult.getSecondLevelId().equals(erjiData.getSecondLevelId())) {
                            erjiData.setJine(tzqkResult.getJine());
                            erjiData.setContent(tzqkResult.getContent());
                            //System.out.println(tzqkResult.getContent());
                            erjiData.setBeiwang(tzqkResult.getBeiwang());
                            //公式
                            erjiData.setFormula(tzqkResult.getFormula());
                        }
                    }
                }
//                else {
//                    //为一级科目放入金额
//                    for (ZxTzqkViewResult yijiData : zxKemuResultList1) {
//                        if (tzqkResult.getFirstLevelId().equals(yijiData.getFirstLevelId())) {
//                            yijiData.setJine(BigDecimal.ZERO);
//                        }
//
//                    }
//                }

            }
        }
        BigDecimal sum = BigDecimal.ZERO;
        //TODO-3 在输出内容中加入一级科目汇总，必须先放一级再放二级，保证tzqk列表显示顺序
        for (ZxTzqkViewResult yijiData : zxKemuResultList1) {
            BigDecimal sumYiJi = BigDecimal.ZERO;
            //先放入该一级科目保证显示顺序，随后赋值，值照样改变，引用对象是同一个
            list.add(yijiData);
            for (ZxTzqkViewResult erjiData : zxKemuResultList2) {
                erjiData.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
                if (erjiData.getFirstLevelId().equals(yijiData.getFirstLevelId())) {
                    erjiData.setSecondLevelName(erjiData.getName());
                    list.add(erjiData);
                    sumYiJi = sumYiJi.add(erjiData.getJine() == null ? BigDecimal.ZERO : erjiData.getJine());
                }
            }
            yijiData.setJine(sumYiJi);
            yijiData.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
            sum = sum.add(yijiData.getJine() == null ? BigDecimal.ZERO : yijiData.getJine());
            yijiData.setFirstLevelName(yijiData.getName());
        }

        DecimalFormat decimalformat = new DecimalFormat("0.00%");

        //TODO-4.1 占比之和保证为1
        Map<String, Double> lingData = new HashMap<>();
        Map<String, Double> notLingData = new HashMap<>();

        //TODO-4.2 占比=一级科目金额/总金额
        Double sumZhanBi = 0d;

        for (ZxTzqkViewResult kemuData : list) {
            //一级科目
            if (!StringUtils.isEmpty(kemuData.getFirstLevelName())) {
                //合计为0或者一级科目金额为0，占比为0
                if (sum.compareTo(BigDecimal.ZERO) == 0 || kemuData.getJine().compareTo(BigDecimal.ZERO) == 0) {
                    kemuData.setPercentage(decimalformat.format(0));
                    lingData.put(kemuData.getFirstLevelId() + kemuData.getFirstLevelName(), 0d);
                    continue;
                }
                //占比
                double per = kemuData.getJine().divide(sum, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
                notLingData.put(kemuData.getFirstLevelId() + kemuData.getFirstLevelName(), per);
                sumZhanBi = sumZhanBi + per;
                kemuData.setPercentage(decimalformat.format(per));
            }
        }

        //TODO-4.3 占比之和保证为1
        if (sumZhanBi != 1) {
            if (notLingData.size() > 0) {
                //如果就一个值大于0，将其值置为1
                if (notLingData.size() == 1) {
                    for (Map.Entry<String, Double> m : notLingData.entrySet()) {
                        notLingData.put(m.getKey(), 1d);
                        //改变对应的值
                        this.resetPercentage(list, m.getKey(), 1d);
                    }
                }
                //如果为多个值，值之和必须为1
                if (notLingData.size() >= 2) {
                    //和小于1，把差值补给第一个值
                    if (sumZhanBi < 1) {
                        double chazhi = 1 - sumZhanBi;
                        for (Map.Entry<String, Double> m : notLingData.entrySet()) {
                            Double value = m.getValue();
                            notLingData.put(m.getKey(), value + chazhi);
                            //改变对应的值
                            this.resetPercentage(list, m.getKey(), value + chazhi);
                            break;
                        }
                    }
                    //和大于1，把差值在第一个值减去
                    if (sumZhanBi > 1) {
                        double chazhi = sumZhanBi - 1;
                        for (Map.Entry<String, Double> m : notLingData.entrySet()) {
                            Double value = m.getValue();
                            notLingData.put(m.getKey(), value - chazhi);
                            //改变对应的值
                            this.resetPercentage(list, m.getKey(), value - chazhi);
                            break;
                        }
                    }
                }
            }
        }

        //总价
        ZxTzqkViewResult result = new ZxTzqkViewResult();
        result.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        //成本合计
        result.setFirstLevelName("总计");
        result.setJine(sum);
        list.add(result);
        //总投资
        ZxTzqkViewResult result1 = new ZxTzqkViewResult();
        result1.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        result1.setSecondLevelName("总投资");
        result1.setJine(mdzx.getYujiTouzi());
        list.add(result1);
        //投资剩余
        ZxTzqkViewResult result2 = new ZxTzqkViewResult();
        result2.setBtyZxMdzxId(mdzx.getBtyZxMdzxId());
        result2.setSecondLevelName("投资剩余");
        result2.setJine(mdzx.getTouzishengyu());
        list.add(result2);
        return list;
    }

    @Override
    public List<ZxTzqkResult> mdList(Long btyZxMdzxId) {
        return baseMapper.mdList(btyZxMdzxId);
    }

    @Override
    public List<MdzxResult> dzExportList(MdzxParam param) {
        return baseMapper.dzExportList(param);
    }

    @Override
    public List<MdzxResult> listJgcDetail(Long btyZxMdzxId) {
        return baseMapper.listJgcDetail(btyZxMdzxId);
    }

    @Override
    public List<MdzxResult> ghsLockList(Long btyZxMdzxId) {
        return baseMapper.ghsLockList(btyZxMdzxId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData getGhsLock(Long btyZxMdzxId) {
        //System.out.println("btyZxMdzxId:"+btyZxMdzxId);
        try {
            //获取门店是否有对应的供货商
            List<MdzxResult> lists = baseMapper.ghsLockList(btyZxMdzxId);
            if (lists.size() == 0) {
                return ResponseData.error(503, "无对应的供货商,无须锁定！");
            }
            Mdzx mdzx = baseMapper.selectById(btyZxMdzxId);
            Integer ghsLocks = mdzx.getGhsLock();
            if (ghsLocks == 0) {
                mdzx.setGhsLock(1);
                baseMapper.updateById(mdzx);

                //先删除,再插入
                ghsLockMapper.delete(new QueryWrapper<BtyZxGhsLock>().eq("bty_zx_mdzx_id", btyZxMdzxId));
                List<MdzxResult> list = baseMapper.ghsLockList(btyZxMdzxId);
                for (MdzxResult mdzxResult : list) {
                    BtyZxGhsLock ghsLock = new BtyZxGhsLock();
                    //1锁定,0解锁
                    ghsLock.setLock(1);
                    ghsLock.setBtyZxMdzxId(btyZxMdzxId);
                    ghsLock.setName(mdzxResult.getXm());
                    ghsLockService.save(ghsLock);
                }
            } else if (ghsLocks == 1) {
                mdzx.setGhsLock(0);
                baseMapper.updateById(mdzx);
                //先删除,再插入
                ghsLockMapper.delete(new QueryWrapper<BtyZxGhsLock>().eq("bty_zx_mdzx_id", btyZxMdzxId));
                List<MdzxResult> list = baseMapper.ghsLockList(btyZxMdzxId);
                for (MdzxResult mdzxResult : list) {
                    BtyZxGhsLock ghsLock = new BtyZxGhsLock();
                    //1锁定,0解锁
                    ghsLock.setLock(0);
                    ghsLock.setBtyZxMdzxId(btyZxMdzxId);
                    ghsLock.setName(mdzxResult.getXm());
                    ghsLockService.save(ghsLock);
                }

            }
            return ResponseData.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseData.error(503, e.getMessage());
        }
    }

    private InputStream exportHandler(List<Map<String, Object>> mingxiList, String name) {
        logger.info("exportHandler start...");

        ByteArrayOutputStream out = null;
        InputStream is = null;

        // 保留1000条数据在内存中
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet();
        //报表样式
        CellStyle contentStyle = ExcelFormatUtil.contentStyle(wb);

        //设置第一行标题：指定 4 个参数，起始行，结束行，起始列，结束列,
        int firstRow = 1;
        int lastRow = 1;
        int firstCol = 1;
        int lastCol = 9;

        SXSSFRow row1 = sheet.createRow(0);
        row1.setHeight((short) 600);
        SXSSFCell cell0 = row1.createCell(0);
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, lastCol - 1));
        cell0.setCellValue(name);
        cell0.setCellStyle(ExcelFormatUtil.titleSytle(wb));

        //设置内容标题
        int contentTitleStartRow = 2;
        String[] titles = new String[]{"厂家名称", "货品名称", "单位", "尺寸", "数量", "单价", "进货总价", "店价", "单店总价"};
        // 字段名所在表格的宽度，数量应与列字段名数量一致
        int[] withs = new int[]{5000, 5000, 5000, 5000, 5000, 5200, 5000, 5000, 5000};
        // 设置报表头样式,cell样式
        CellStyle headSytle = ExcelFormatUtil.headSytle(wb);
        ExcelFormatUtil.initContentTitleEX(sheet, headSytle, contentTitleStartRow, titles, withs);

        int contentStartRow = 2;
        String bei = "1.05";
//        BigDecimal b = new BigDecimal(bei);
        Set<String> cdSet = new HashSet<String>();
//        cdSet.add("彭湘千");
//        cdSet.add("张杰");
//        cdSet.add("梁家昭");
//        cdSet.add("聂维霞");
        //添加数据字典里的供货商 by zwf
        String jiagongcai_ghs = (String) ConstantsContext.getConstntsMap().get("jiagongcai_ghs");
        if (jiagongcai_ghs != null && !jiagongcai_ghs.equals("")) {
            String[] ghsArr = jiagongcai_ghs.split(",");
            for (String ghs : ghsArr) {
                cdSet.add(ghs);
            }
        }
        //改回去
//        List<MdzxResult>list=baseMapper.ghsList();
//        if(list.size()>0){
//            for (MdzxResult mdzxResult : list) {
//                cdSet.add(mdzxResult.getGhs());
//            }
//        }


        for (int i = 0; i < mingxiList.size(); i++) {
            Map<String, Object> mx = mingxiList.get(i);
            if (ToolUtil.isEmpty(mx)) {
                continue;
            }
            SXSSFRow row = sheet.createRow(contentStartRow);
            int row_index = contentStartRow + 1;
            int j = 0;
            SXSSFCell cell = row.createCell(j++);//厂家名称
            cell.setCellValue(mx.get("xm") != null ? mx.get("xm").toString() : "");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//huopin名称
            cell.setCellValue(mx.get("hpName") != null ? mx.get("hpName").toString() : "");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//单位
            cell.setCellValue(mx.get("danwei") != null ? mx.get("danwei").toString() : "");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//规格型号
            cell.setCellValue(mx.get("guige") != null ? mx.get("guige").toString() : "");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//数量
            BigDecimal shuliang = mx.get("shuliang") != null ? new BigDecimal(mx.get("shuliang").toString()) : new BigDecimal(0);
            cell.setCellValue(shuliang.toString());
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//单价
            BigDecimal danjia = mx.get("danjia") != null ? new BigDecimal(mx.get("danjia").toString()) : new BigDecimal(0);
            cell.setCellValue(danjia.toString());
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//进货总价-
            //BigDecimal zj=shuliang.multiply(danjia);
            //cell.setCellValue(zj.toString());
            cell.setCellFormula("E" + row_index + "*F" + row_index);
            cell.setCellStyle(contentStyle);


            cell = row.createCell(j++);//店价-
//            cell.setCellValue(danjia.multiply(b).toString());
            if (cdSet.contains(mx.get("xm"))) {
                cell.setCellFormula("F" + row_index + "*" + bei);
            } else {
                cell.setCellFormula("F" + row_index);
            }

            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//单店总价-
//            cell.setCellFormula();
//            BigDecimal ddzj = zj.multiply(b).setScale(2,BigDecimal.ROUND_UP);
//            cell.setCellValue(ddzj.toString());
            if (shuliang.doubleValue() != 0 && danjia.doubleValue() != 0) {
                cell.setCellFormula("E" + row_index + "*H" + row_index);
            } else {
                BigDecimal jine = mx.get("jine") != null ? new BigDecimal(mx.get("jine").toString()) : new BigDecimal(0);
                cell.setCellValue(jine.toString());
            }

            cell.setCellStyle(contentStyle);

            contentStartRow++;
        }
        //合计
        {
            SXSSFRow row = sheet.createRow(contentStartRow);
            SXSSFCell cell = row.createCell(8);//单店总价-
            cell.setCellFormula("SUM(I3:I" + (mingxiList.size() + 2) + ")");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(6);//单店总价-
            cell.setCellFormula("SUM(G3:G" + (mingxiList.size() + 2) + ")");
            cell.setCellStyle(contentStyle);
        }
        try {
            out = new ByteArrayOutputStream();
            wb.write(out);
            is = new ByteArrayInputStream(out.toByteArray());
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        logger.info("exportHandler end...");
        return is;
    }

}
